import React, {useState, useEffect} from 'react';
import './App.css';


const getItemMsg = (id, list) => {
  let msgItem = {};
  list.map(item => {
    if (item.id === id) {
      msgItem = item
    }
  });
  list = null;
  msgItem.pid = id;
  return msgItem
}

const MoveItem = (props) => {
  const [transform, setTransform] = useState({})

  const onDragStartActive = (ev) => {
    props.onDragStartActive(`item-${props.id}-${props.index}`, props.index, ev, props.id, props.pid)
  }

  const onDragEnterActive = (ev) => {
    props.onDragEnterActive(props.item.title, props.index, ev, props.id, props.pid, `item-${props.id}-${props.index}`)
  }

  useEffect(() => {
    changeTransForm();
  }, [props.changeIndex])

  const changeTransForm = () => {
    if (!props.changeIndex.index && props.changeIndex.index !== 0) { //此时没有要移动的情况出现
      setTransform({
        transform: `translate3d(0px, 0px, 0px)`,
        transitionDuration: "300ms"
      });
      return false;
    }

    //如果是同一个父节点下的从下往上拖拽
    if (
        props.changeIndex.pid === props.moveIndex.pid &&
        props.pid === props.changeIndex.pid &&
        props.index <= props.moveIndex.index &&
        props.index >= props.changeIndex.index
    ) {
      setTransform({
        transform: `translate3d(0px, ${props.initClient.height}px, 0px)`,
        transitionDuration: "300ms"
      });
      return ;
    }

    //如果是同一个父节点下的从上往下拖拽
    if (
        props.changeIndex.pid === props.moveIndex.pid &&
        props.pid === props.changeIndex.pid &&
        props.index >= props.moveIndex.index &&
        props.index <= props.changeIndex.index
    ) {
      setTransform({
        transform: `translate3d(0px, -${props.initClient.height}px, 0px)`,
        transitionDuration: "300ms"
      });
      return ;
    }

    //如果不是同一个父节点且从上往下
    if (
        props.changeIndex.pid !== props.moveIndex.pid &&
        props.enterBody &&
        props.bodyId === props.pid

    ) {
      console.log("进入了父级");
      return ;
    }


    //如果不是同一个父节点且从下往上
    if (
        props.changeIndex.pid !== props.moveIndex.pid &&
        props.enterBody &&
        props.bodyId === props.pid
    ) {
      console.log("进入了父级");
      return ;
    }

    setTransform({
      transform: `translate3d(0px, 0px, 0px)`,
      transitionDuration: "300ms"
    });

  }

  const dragStopActive = {
    onMouseDown: (e) => {
      // e.preventDefault();
      e.stopPropagation();
    },
    onDragStart: (e) => {
      // e.preventDefault();
      e.stopPropagation();
    },
    onDrag: (e) => {
      // e.preventDefault();
      e.stopPropagation();
    },
    onDragEnd: (e) => {
      // e.preventDefault();
      e.stopPropagation();
    }
  }

  const onDragEnter = (ev) => {
    ev.stopPropagation();
    document.getElementById(`list-item-body-${props.id}`).style.paddingBottom = '180px';
    if (props.bodyId === props.id) return ;
    props.enterBody(props.id);
  }

  const onDragLeave = (ev) => {
    document.getElementById(`list-item-body-${props.id}`).style.paddingBottom = '20px';
    ev.stopPropagation()
  }
 
  return (
      <div
          key={`item-${props.id}`}
          id={`item-${props.id}-${props.index}`}
          style={{margin: '0px auto 20px auto', ...transform}}
          className={'move-active-item'}
          draggable
          onDragStart={onDragStartActive}
          onDrag={props.dragActive}
          onDragEnd={props.dragEndActive}
      >
        <h4 onDragEnter={onDragEnterActive} onClick={() => {console.log(111111)}} >{props.item.title} -- {props.pid} -- {props.index}</h4>
        <div {...dragStopActive} className="desc-ele">{props.item.desc}</div>
        {
          props.item.type === 2 &&
          <div {...dragStopActive} onDragOver={onDragEnter} onDragLeave={onDragLeave} id={`list-item-body-${props.id}`} className="list-item-body">
            大body题部分大body题部分大body题部分大body题部分大body题部分大body题部分大body题部分
            {
              props.listMap[props.id]?.map((item, index) => (
                  <MoveItem key={item}
                            item={getItemMsg(item, JSON.parse(JSON.stringify(props.list)))}
                            id={item}
                            pid={props.id}
                            index={index}
                            changeIndex={props.changeIndex}
                            initClient={props.initClient}
                            moveIndex={props.moveIndex}
                            onDragStartActive={props.onDragStartActive}
                            dragActive={props.dragActive}
                            dragEndActive={props.dragEndActive}
                            onDragEnterActive={props.onDragEnterActive}
                            enterBody={props.enterBody}
                            bodyId={props.bodyId}
                            dragEnterStation={props.dragEnterStation}
                            list={JSON.parse(JSON.stringify(props.list))}
                            listMap={JSON.parse(JSON.stringify(props.listMap))}
                  />
              ))
            }
          </div>
        }
      </div>
  )
}
let processBoxEle = null;
let processCopiedEle = null;
let initClient = {x: 0, y: 0, height: 0};
let moveIndex = {index: null, id: null,  pid: null};
let initPid = "0";
let bodyEnter = false;
let bodyId = "";
let dragEnterStation = "top"; //top：从上面过来，bottom：从下面过来

const App = () => {
  const [list, setList] = useState([]);
  // const [list, setList] = useState(["test1", "test2", "test3"]);
  const [listObj, setListObj] = useState({
    list: [],
    relations: {}
  })
  const [changeIndex, setChangeIndex] = useState({index: null, id: null, pid: null});

  useEffect(() => {
    fetch("./list.json").then(response => {
      response.json().then(msg => {
        setListObj(msg)
      }).catch(err => {
        console.error(err)
      })
    }).catch(err => {
      console.error(err)
    })
  }, [])


  const onDragStartActive = (ids, index, ev, id, pid) => {
    processBoxEle = document.getElementById(ids);
    let rectCode = processBoxEle.getBoundingClientRect();
    initClient = {x: rectCode.x - ev.clientX, y: rectCode.y - ev.clientY, height: rectCode.height}
    bodyEnter = false;
    //
    // processCopiedEle = processBoxEle.cloneNode(true);
    // processCopiedEle.style.display = "none";
    // processCopiedEle.style.position = "fixed";
    // processCopiedEle.style.textAlign = "center";
    // processCopiedEle.style["pointer-events"] = "none";
    // processBoxEle.style.opacity = "0";
    // document.body.appendChild(processCopiedEle);
    moveIndex = {index: index, id: id, pid: pid};
    // document.body.style.cursor = "-webkit-grabbing";
    setChangeIndex({index: null, id: null, pid: null});
  }

  const dragActive = (ev) => {
    // processBoxEle.style.display = "none";
    processBoxEle.style.opacity = "0";
    // processCopiedEle.style.display = "block";
    // processCopiedEle.style.left = `${ev.clientX + initClient.x}px`;
    // processCopiedEle.style.top = `${ev.clientY + initClient.y}px`;
    // processCopiedEle.style["transform-origin"] = "0 0";
  }

  const dragEndActive = (ev) => {
    // document.body.removeChild(processCopiedEle);
    // processCopiedEle = null;
    processBoxEle.style.opacity = "1";
    // processBoxEle.style.display = "block";
    // processBoxEle = null;
    afterDrag();
    // processBoxEle = null;
    // initClient = {x: 0, y: 0, height: 0}
    // setChangeIndex({index: null, pid: null});
    // moveIndex = {index: null, pid: null};
  }

  const onDragEnterActive = (title, index, ev, id, pid, ids) => {
    bodyEnter = false;
    if (changeIndex.index !== index || changeIndex.pid !== pid || changeIndex.id !== id) {
      setChangeIndex({index: index, id: id, pid: pid});
      let enterEle = document.getElementById(ids).getBoundingClientRect();
      if (ev.clientY > enterEle.top) {
        dragEnterStation = "bottom"
      } else {
        dragEnterStation = "top"
      }
      enterEle = null;
    }

  }

  const enterBody = (id) => {
    if (bodyId === id) return ;
    bodyEnter = true;
    bodyId = id;

    console.log(id)
  }

  const afterDrag = () => {
    if ((!changeIndex.index || changeIndex.index === moveIndex.index) && changeIndex.index !== 0 && !bodyEnter) {
      processBoxEle = null;
      moveIndex = {index: null, id: null, pid: null};
      setChangeIndex({index: null, id: null, pid: null});
      return ;
    }

    let relations = {...listObj.relations};
    let list = [...listObj.list];

    relations[moveIndex.pid].splice(moveIndex.index, 1); //不管如何先把初始位置的干掉
    if (bodyEnter && relations[bodyId] !== undefined && dragEnterStation === "top") { //仅是进入新节点的body内
      relations[bodyId].unshift(moveIndex.id);
    } else if (bodyEnter && relations[bodyId] !== undefined && dragEnterStation === "bottom") { //仅是进入新节点的body内
      relations[bodyId].push(moveIndex.id);
    } else if (relations[changeIndex.pid][changeIndex.index] === changeIndex.id) { //证明不是同一个父节点（已经去掉滑动节点之后根据新的位置判断靠谱）
      relations[changeIndex.pid].splice(changeIndex.index, 0, moveIndex.id);
    } else if (moveIndex.index > changeIndex.index) { //往上滑动
      relations[changeIndex.pid].splice(changeIndex.index - 1, 0, moveIndex.id);
    } else { //往下滑动
      relations[changeIndex.pid].splice(changeIndex.index, 0, moveIndex.id);
    }


    // eslint-disable-next-line no-unused-expressions
    // relations[changeIndex.pid].splice(changeIndex + 1, 0, moveIndex.id);

    setListObj({
      list: list,
      relations: relations
    })


    bodyEnter = false;
    relations = null;
    list = null;
    processBoxEle = null;
    setChangeIndex({index: null, id: null, pid: null});
    moveIndex = {index: null, id: null, pid: null};
  }

  return (
    <div className="App">
      {
        listObj.relations[initPid]?.map((item,index) => (
            <MoveItem key={item}
                      pid={"0"}
                      index={index}
                      item={getItemMsg(item, [...listObj.list])}
                      id={item}
                      changeIndex={changeIndex}
                      initClient={initClient}
                      moveIndex={moveIndex}
                      onDragStartActive={onDragStartActive}
                      dragActive={dragActive}
                      dragEndActive={dragEndActive}
                      onDragEnterActive={onDragEnterActive}
                      enterBody={enterBody}
                      bodyId={bodyId}
                      dragEnterStation={dragEnterStation}
                      list={JSON.parse(JSON.stringify(listObj.list))}
                      listMap={JSON.parse(JSON.stringify(listObj.relations))}
            />
        ))
      }
    </div>
  );
}

export default App;
